Namespace.Use("UI.Object", function(ns) {
    //
    //  Imports.
    //
    var Inherit = Namespace.Import("Base.Inherit");

    //
    //  Global.
    //
    var cst_InitialX = 0, cst_InitialY = 0;
    var cst_InitialWidth = 100, cst_InitialHeight = 100;
    var cst_InitialVisibility = true;
    var cst_InitialLayer = 0;

    //
    //  Classes.
    //
    var ImageBox = Polymorphic.Create(
        [String],
        function(source) {
            //  Let parent class initialize.
            ns.BaseObject.call(this);

            //
            //  Members.
            //
            var last_x = -1, last_y = -1;
            var x = cst_InitialX, y = cst_InitialY;
            var last_width = -1, last_height = -1;
            var width = cst_InitialWidth, height = cst_InitialHeight;
            var last_visibility = !cst_InitialVisibility;
            var visibility = cst_InitialVisibility;
            var last_layer = -1;
            var layer = cst_InitialLayer;
            var last_source = null;
            var element = $("<img>").css({
                "position": "absolute",
            });

            //
            //  Public methods.
            //
            this.GetHTMLElement = function() {
                return element[0];
            };
            this.Invalidate = function() {
                //  Update the position.
                if (last_x != x) {
                    element.css({
                        "left": x
                    });
                    last_x = x;
                }
                if (last_y != y) {
                    element.css({
                        "top": y
                    });
                    last_y = y;
                }

                //  Update the size.
                if (last_width != width) {
                    element.css({
                        "width": width
                    });
                    last_width = width;
                }
                if (last_height != height) {
                    element.css({
                        "height": height
                    });
                    last_height = height;
                }

                //  Update the visibility.
                if (last_visibility != visibility) {
                    if (visibility == true) {
                        element.show();
                    } else {
                        element.hide();
                    }
                    last_visibility = visibility;
                }

                //  Update the layer.
                if (last_layer != layer) {
                    element.css({
                        "z-index": layer
                    });
                    last_layer = layer;
                }

                //  Update the source.
                if (last_source != source) {
                    if (source === null) {
                        element.removeAttr("src");
                    } else {
                        element.attr("src", source);
                    }
                    last_source = source;
                }
            };
            this.AccessPosition = Polymorphic.Create(
                [],
                function() {
                    return [x, y];
                },
                [Number, Number],
                function(new_x, new_y) {
                    last_x = x;
                    last_y = y;
                    x = new_x;
                    y = new_y;
                    this.Invalidate();
                }
            );
            this.AccessSize = Polymorphic.Create(
                [],
                function() {
                    return [width, height];
                },
                [Number, Number],
                function(new_width, new_height) {
                    last_width = width;
                    last_height = height;
                    width = new_width;
                    height = new_height;
                    this.Invalidate();
                }
            );
            this.AccessVisibility = Polymorphic.Create(
                [],
                function() {
                    return visibility;
                },
                [Boolean],
                function(new_visibility) {
                    last_visibility = visibility;
                    visibility = new_visibility;
                    this.Invalidate();
                }
            );
            this.AccessLayer = Polymorphic.Create(
                [],
                function() {
                    return layer;
                },
                [Number],
                function(new_layer) {
                    last_layer = layer;
                    layer = new_layer;
                    this.Invalidate();
                }
            );
            this.AccessSource = Polymorphic.Create(
                [],
                function() {
                    return source;
                },
                [String],
                function(new_source) {
                    last_source = source;
                    source = new_source;
                    this.Invalidate();
                }
            );

            //  Invalidate immediately after created.
            this.Invalidate();
        }
    );

    //  Inherit "ImageBox" from "BaseObject".
    Inherit(ImageBox, ns.BaseObject);

    //  Export public APIs / classes.
    Namespace.Export(ns, "ImageBox", ImageBox);
});